home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / libs / phigs / ptk.lha / ptk / source / library / stct.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-01  |  12.1 KB  |  404 lines

  1. /*----------------------------------------------------------------------------
  2.  
  3.  Module name: structure content drawer
  4.  
  5.  Author: Toby Howard
  6.  
  7.  Function: This module implements the structure content drawer.
  8.  
  9.  Dependencies:
  10.  
  11.  External function list: 
  12.  
  13.  Internal function list: 
  14.  
  15.  Hashtables used: "structureid", "label".
  16.  
  17.  Modification history : (Version), (Date), (Name), (Description).
  18.  
  19.  1.0, ????, Toby Howard, First version.
  20.  
  21.  1.1, 15th July 1988, Steve Larkin, Modified to work with VAX Phigs.
  22.  
  23.  2.0, 27th August 1991, Gareth Williams, Translated to C.
  24.  
  25.  3.0, June 1992, Gareth Williams, Converted to ISO PHIGS C.
  26.  
  27. ----------------------------------------------------------------------------*/
  28.  
  29. #include <stdio.h>
  30. #include <math.h>
  31. #include <phigs.h>
  32. #include "ptk.h"
  33.  
  34. #define OFFSET 0.025
  35.  
  36. static Pint stctwsid, stfirstel, stlastel, stctfont;
  37. static Pfloat elemheight, elemtypewidth, elemptrwidth;
  38. static Ppoint topleftbox;
  39. static Pint no_els;
  40. static Pint first_element;
  41. static Ppoint tp;
  42.  
  43. /*--------------------------------------------------------------------------*/
  44.  
  45. static void setscaling()
  46. /* computes the transformation to scale the picture
  47. ** into [0,1], and inserts a global transformation at the
  48. ** start of the picture.
  49. */
  50. {
  51.   Pmatrix3 globaltran;
  52.   Pint err, el;
  53.   Pfloat depth;
  54.   Ppoint3 shift, scale;
  55.  
  56.   if ((stlastel - stfirstel) >= 9)
  57.   {
  58.     depth = (stlastel - stfirstel + 2) * 0.1;
  59.     shift = ptk_point3(0.0, -1.0, 0.0);
  60.     ptk_shift3(&shift, PTYPE_REPLACE, globaltran);
  61.     scale = ptk_point3(1.0/depth, 1.0/depth, 1.0);
  62.     ptk_scale3(&scale, PTYPE_POSTCONCAT, globaltran);
  63.     shift = ptk_point3(0.0, 1.0, 0.0);
  64.     ptk_shift3(&shift, PTYPE_POSTCONCAT, globaltran);
  65.   }
  66.   else
  67.     ptk_unitmatrix3(globaltran);
  68.   /* Squeeze in a global transformation at the top of the structure */
  69.   pinq_elem_ptr(&err, &el);
  70.   pset_elem_ptr(first_element);
  71.   pset_elem_ptr_label(ptk_stringtoint("label", "globaltran"));
  72.   pset_global_tran3(globaltran);
  73.   pset_elem_ptr(el + 1);
  74. }  /* setscaling */
  75.  
  76. /*--------------------------------------------------------------------------*/
  77.  
  78. static void initialise()
  79. {
  80.   Pfloat charht;
  81.   Ptext_align align;
  82.   Ppoint elembox;
  83.  
  84.   elemheight = 0.1;
  85.   elemtypewidth = 0.7;
  86.   elemptrwidth = 0.2;
  87.   topleftbox = ptk_point(0.0, 1.0);
  88.  
  89.   align.hor = PHOR_NORM;
  90.   align.vert = PVERT_HALF;
  91.   pset_text_align(&align);
  92.   elembox = ptk_point(elemtypewidth - OFFSET - 0.01, elemheight);
  93.   ptk_computecharheight(stctwsid, "set_annotation_text_character_up_vector", 
  94.                         &elembox, stctfont, &charht);
  95.   pset_char_ht(charht);
  96.   pset_text_font(stctfont);
  97. }  /* initialise */
  98.  
  99. /*--------------------------------------------------------------------------*/
  100.  
  101. static void elemtypebox(C(Pelem_type) eltype, C(Pint) elemnum)
  102. PreANSI(Pelem_type eltype)
  103. PreANSI(Pint elemnum)
  104. /* 
  105. ** Assumes there is no local tran in effect 
  106. */
  107. {
  108.   Ppoint pts[4];
  109.   char str[50];
  110.   Pint totlen;
  111.   Ppoint_list sets;
  112.  
  113.   pts[0] = topleftbox;
  114.   pts[1] = ptk_point(pts[0].x + elemtypewidth, pts[0].y);
  115.   pts[2] = ptk_point(pts[1].x, pts[0].y - elemheight);
  116.   pts[3] = ptk_point(pts[0].x, pts[2].y);
  117.   sets.num_points = 4;
  118.   sets.points = pts;
  119.   ptk_fillareaset(1, &sets);
  120.   ptk_getelemtypename(eltype, 50, str, &totlen);
  121.   tp = ptk_point(topleftbox.x + OFFSET, topleftbox.y - 0.05);
  122.   ptext(&tp, str);
  123.   sprintf(str, "%d\0", elemnum);
  124.   tp = ptk_point(topleftbox.x + elemtypewidth + OFFSET, 
  125.                  topleftbox.y - 0.05);
  126.   ptext(&tp, str);
  127. }  /* elemtypebox */
  128.  
  129. /*--------------------------------------------------------------------------*/
  130.  
  131. /*function:external*/
  132. extern void ptk_structcontent(C(Pint) wsid, C(Pint) stid, C(Pint) firstel, 
  133.                               C(Pint) lastel, C(Pint) elemptr, C(Pint) font,
  134.                   C(Pint *) error)
  135. PreANSI(Pint wsid)
  136. PreANSI(Pint stid)
  137. PreANSI(Pint firstel)
  138. PreANSI(Pint lastel)
  139. PreANSI(Pint elemptr)
  140. PreANSI(Pint font)
  141. PreANSI(Pint *error)
  142. /*
  143. ** \parambegin
  144. ** \param{Pint}{wsid}{workstation identifier}{IN}
  145. ** \param{Pint}{stid}{structure identifier}{IN}
  146. ** \param{Pint}{firstel}{first element in range}{IN}
  147. ** \param{Pint}{lastel}{last element in range}{IN}
  148. ** \param{Pint}{elemptr}{element pointer}{IN}
  149. ** \param{Pint}{font}{text font}{IN}
  150. ** \param{Pint *}{error}{error code}{OUT}
  151. ** \paramend
  152. ** \blurb{This function inserts a diagram of the contents of the structure
  153. ** {\tt stid} in the currently open structure at the current editing 
  154. ** position. The diagram consists of a table of elements represented
  155. ** by rectangles and labelled with element type and number. The table
  156. ** has a heading with the format:
  157. ** {\tt "structure N "name" (M elements)"}
  158. ** where N is the structure identifier, name is the structure name
  159. ** extracted from the "structureid" hashtable and M is the total
  160. ** number of elements in the structure. The error code = 1 if there
  161. ** is no open structure and = 2 if {\tt stid} doesn't exist.
  162. ** This function requires hashtable "label".} 
  163. */
  164. {
  165.   Popen_struct_status structst;
  166.   Pint i, err, curname, lenstr, elptr;
  167.   Pelem_type etype;
  168.   char str[80], name[30];
  169.   Ppoint3 arrowcentre;
  170.   Ppoint3 arrowshift;
  171.   Pmatrix3 mat;
  172.  
  173.   stctwsid = wsid;
  174.   stfirstel = firstel;
  175.   stlastel = lastel;
  176.   stctfont = font;
  177.   *error = 0;
  178.  
  179.   pinq_open_struct(error, &structst, &curname);
  180.   if (structst == PSTRUCT_NONE) 
  181.   {
  182.     *error = 1;
  183.     fprintf(stderr, "ptk_structcontent: needs a structure open\n");
  184.     return;
  185.   }
  186.  
  187.   if (!ptk_structexists(stid)) 
  188.   {
  189.     *error = 2;
  190.     fprintf(stderr, "ptk_structcontent: structure %d doesn't exist\n", stid);
  191.     return;
  192.   }
  193.  
  194.   ptk_seteditmode(PEDIT_INSERT);
  195.   /* validate the requested element range */
  196.   no_els = ptk_elemcount(stid);
  197.   if (stfirstel <= 0)
  198.     stfirstel = 1;
  199.   if ((stlastel > no_els) || (stlastel == 0))
  200.     stlastel = no_els;
  201.   if (stlastel < stfirstel)
  202.     stlastel = stfirstel;
  203.  
  204.   pinq_elem_ptr(&err, &first_element);
  205.   plabel(ptk_stringtoint("label", "globaltran"));
  206.   plabel(ptk_stringtoint("label", "elementpointer"));
  207.   plabel(ptk_stringtoint("label", "start-structcontent"));
  208.   ptk_unitmatrix3(mat);
  209.   pset_local_tran3(mat, PTYPE_REPLACE);
  210.   initialise();
  211.  
  212.   /* heading */
  213.   if (ptk_hashtableused("structureid"))
  214.   {
  215.     ptk_inttostring("structureid", stid, 30, name, &lenstr);
  216.     if (lenstr != 0)
  217.       sprintf(str, "structure %d \"%s\" (%d elements)\0", stid, 
  218.               name, no_els); 
  219.     else
  220.       sprintf(str, "structure %d (%d elements)\0", stid, 
  221.               no_els); 
  222.   }
  223.   tp = ptk_point(topleftbox.x + OFFSET, topleftbox.y - 0.05);
  224.   ptext(&tp, str);  
  225.   topleftbox.y -= elemheight;
  226.   /* elements */
  227.   for (i = stfirstel; i <= stlastel; i++) 
  228.   {
  229.     ptk_inqelemtype(stid, i, error, &etype);
  230.     if (*error != 0)
  231.       etype = PELEM_NIL;
  232.     pset_pick_id(i);   /* pick identifier = element pointer */
  233.     elemtypebox(etype, i);
  234.     if (i == elemptr)
  235.     {    
  236.       pinq_elem_ptr(&err, &elptr);
  237.       pset_elem_ptr(0);
  238.       pset_elem_ptr_label(ptk_stringtoint("label", "elementpointer"));
  239.       arrowshift = ptk_point3(0.9, topleftbox.y - 0.05, 0.0);
  240.       ptk_shift3(&arrowshift, PTYPE_REPLACE, mat);
  241.       pset_local_tran3(mat, PTYPE_REPLACE);
  242.       /* insert arrow */
  243.       arrowcentre = ptk_point3(0.0, 0.0, 0.0);
  244.       ptk_arrow(0.1, 0.075, &arrowcentre, 90.0);
  245.       /* jump back */
  246.       pset_elem_ptr(elptr + 2);
  247.     }
  248.     topleftbox.y -= elemheight;
  249.   }
  250.  
  251.   setscaling();
  252.   plabel(ptk_stringtoint("label", "end-structcontent"));
  253.   ptk_unseteditmode();
  254. }  /* ptk_structcontent */
  255.  
  256. /*--------------------------------------------------------------------------*/
  257.  
  258. /*function:external*/
  259. extern void ptk_inqstructcontentrange(C(Pint) contentstid, C(Pint *) firstel,
  260.                                       C(Pint *) lastel, C(Pint *) err)
  261. PreANSI(Pint contentstid)
  262. PreANSI(Pint *firstel)
  263. PreANSI(Pint *lastel)
  264. PreANSI(Pint *err)
  265. /*
  266. ** \parambegin
  267. ** \param{Pint}{contentstid}{content structure identifier}{IN}
  268. ** \param{Pint *}{firstel}{element pointer}{OUT}
  269. ** \param{Pint *}{lastel}{element pointer}{OUT}
  270. ** \param{Pint *}{err}{error indicator}{OUT}
  271. ** \paramend
  272. ** \blurb{This function may be used to obtain the element range which appears
  273. ** in the structure content diagram. The error code = 1 if {\tt contentstid}
  274. ** is not a structure content diagram.}
  275. */
  276. {
  277.   Pint elptr, lstnum;
  278.   ptkselcontent elcont;
  279.   Psearch_status stat;
  280.   Pstore store;
  281.   Pelem_type eltype;
  282.  
  283.   *err = 0;
  284.   ptk_openstruct(contentstid);
  285.   pset_elem_ptr(0);
  286.   if (ptk_findlabel(ptk_stringtoint("label", "start-structcontent"), &elptr))
  287.   {
  288.     pset_elem_ptr(0);
  289.     pset_elem_ptr_label(ptk_stringtoint("label", "start-structcontent"));
  290.     eltype = PELEM_TEXT;
  291.     ptk_findelemtype(&eltype, 1, PDIR_FORWARD, &stat, &elptr, &lstnum);
  292.     pset_elem_ptr(elptr + 1);
  293.     ptk_findelemtype(&eltype, 1, PDIR_FORWARD, &stat, &elptr, &lstnum);
  294.     pset_elem_ptr(elptr + 1);
  295.     ptk_findelemtype(&eltype, 1, PDIR_FORWARD, &stat, &elptr, &lstnum);
  296.     pcreate_store(err, &store);
  297.     if (stat == PSEARCH_STATUS_SUCCESS)
  298.     {
  299.       ptk_inqelemtypesizecontent(contentstid, elptr, store, err, &elcont);
  300.       *firstel = atoi(elcont.eldata->text.char_string);
  301.     }
  302.     pset_elem_ptr_label(ptk_stringtoint("label", "end-structcontent"));
  303.     ptk_findelemtype(&eltype, 1, PDIR_BACKWARD, &stat, &elptr, &lstnum);
  304.     if (stat == PSEARCH_STATUS_SUCCESS)
  305.     {
  306.       ptk_inqelemtypesizecontent(contentstid, elptr, store, err, &elcont);
  307.       *lastel = atoi(elcont.eldata->text.char_string);
  308.     }
  309.     ptk_delstore(store);
  310.   }
  311.   else
  312.     *err = 1;
  313.   ptk_closestruct();
  314. }  /* ptk_inqstructcontentrange */
  315.  
  316. /*--------------------------------------------------------------------------*/
  317.  
  318. /*function:external*/
  319. extern void ptk_setstructcontentelemptr(C(Pint) contentstid, C(Pint) elemptr)
  320. PreANSI(Pint contentstid)
  321. PreANSI(Pint elemptr)
  322. /*
  323. ** \parambegin
  324. ** \param{Pint}{contentstid}{content structure identifier}{IN}
  325. ** \param{Pint}{elemptr}{element pointer}{IN}
  326. ** \paramend
  327. ** \blurb{This function draws an arrow pointing the element {\tt elemptr}
  328. ** in the structure content diagram.}
  329. */
  330. {
  331.   Pint range1, range2, err;
  332.   Ppoint3 arrowcentre;
  333.   Ppoint3 arrowshift;
  334.   Pmatrix3 mat;
  335.  
  336.   /* find element range */
  337.   ptk_inqstructcontentrange(contentstid, &range1, &range2, &err);
  338.   if (err == 0)
  339.   {
  340.     if ((elemptr >= range1) && (elemptr <= range2))
  341.     {
  342.       ptk_openstruct(contentstid);
  343.       pset_elem_ptr(0);
  344.       pdel_elems_labels(ptk_stringtoint("label", "elementpointer"),
  345.                       ptk_stringtoint("label", "start-structcontent"));
  346.       arrowshift = ptk_point3(0.9, 0.0, 0.0);
  347.       arrowshift.y = 0.95 + (-0.1 * (Pfloat)(elemptr - range1 + 1));
  348.       ptk_shift3(&arrowshift, PTYPE_REPLACE, mat);
  349.       pset_pick_id(elemptr);
  350.       pset_local_tran3(mat, PTYPE_REPLACE);
  351.       /* insert arrow */
  352.       arrowcentre = ptk_point3(0.0, 0.0, 0.0);
  353.       ptk_arrow(0.1, 0.075, &arrowcentre, 90.0);
  354.       ptk_closestruct();
  355.     }
  356.   }  
  357. }  /* ptk_setstructcontentelemptr */
  358.  
  359. /*--------------------------------------------------------------------------*/
  360.  
  361. /*function:external*/
  362. extern void ptk_inqstructcontentelemptr(C(Pint) contentstid, 
  363.                      C(Pint *) elemptr, C(Pint *) err)
  364. PreANSI(Pint contentstid)
  365. PreANSI(Pint *elemptr)
  366. PreANSI(Pint *err)
  367. /*
  368. ** \parambegin
  369. ** \param{Pint}{contentstid}{content structure identifier}{IN}
  370. ** \param{Pint *}{elemptr}{element pointer}{OUT}
  371. ** \param{Pint *}{err}{error indicator}{OUT}
  372. ** \paramend
  373. ** \blurb{This function may be used to obtain the element number pointed
  374. ** to by the element arrow in the structure content diagram.
  375. ** The error code = 1 if {\tt contentstid} is not a 
  376. ** structure content diagram.}
  377. */
  378. {
  379.   Psearch_status stat;
  380.   Pint elptr, lstnum;
  381.   Pelem_type elemlist[2];
  382.  
  383.   *err = 0;
  384.   ptk_openstruct(contentstid);
  385.   pset_elem_ptr(0);
  386.   if (ptk_findlabel(ptk_stringtoint("label", "elementpointer"), &elptr))
  387.   {
  388.     pset_elem_ptr_label(ptk_stringtoint("label", "elementpointer"));
  389.     poffset_elem_ptr(1);
  390.     elemlist[0] = PELEM_PICK_ID;
  391.     elemlist[1] = PELEM_LABEL;
  392.     ptk_findelemtype(elemlist, 2, PDIR_FORWARD, &stat, &elptr, &lstnum);
  393.     if ((stat == PSEARCH_STATUS_SUCCESS) && (lstnum == 0))
  394.       ptk_getpickid(contentstid, elptr, elemptr);
  395.   }
  396.   else
  397.     *err = 1;
  398.   ptk_closestruct();
  399. }  /* ptk_inqstructcontentelemptr */
  400.  
  401. /*--------------------------------------------------------------------------*/
  402.  
  403. /* end of stct.c */
  404.